import axios from 'axios'
import router from '@/router'

axios.defaults.baseURL = '/api'
axios.defaults.timeout = 3600
let MessageBox_401_show = false

// HTTP request 拦截器
axios.interceptors.request.use(
	(config) => {
		let token = tool.cookie.get('token')
		if (token) {
			config.headers['token'] = token
		}
		if (config.method == 'get') {
			config.params = config.params || {}
			config.params['_'] = new Date().getTime()
		}
		if (config.method == 'post' || config.method == 'put' || config.method == 'patch' || config.method == 'delete') {
			if (config.url !== '/auth/token' && config.url !== '/system/websetlang') {
				const user = tool.data.get('USER')
				config.data = tool.generateApiSignature(config.data, user.salt)
			}
		}
		return config
	},
	(error) => {
		return Promise.reject(error)
	}
)

// HTTP response 拦截器
axios.interceptors.response.use(
	(response) => {
		return response
	},
	(error) => {
		if (error.response) {
			if (error.response.status == 401) {
				if (!MessageBox_401_show) {
					MessageBox_401_show = true
					ElMessageBox.confirm('当前用户已被登出或无权限访问当前资源，请尝试重新登录后再操作。', '无权限访问', {
						type: 'error',
						closeOnClickModal: false,
						center: true,
						confirmButtonText: '重新登录',
						cancelButtonText: '取消',
						beforeClose: (_action, _instance, done) => {
							MessageBox_401_show = false
							done()
						}
					})
						.then(() => {
							tool.cookie.remove('token')
							router.replace({ path: '/login' })
						})
						.catch(() => {})
				}
			} else if (error.response.status == 404) {
				ElNotification.error({
					title: '请求错误',
					message: 'Status:404，正在请求不存在的服务器记录！'
				})
			} else if (error.response.status == 500) {
				ElNotification.error({
					title: '请求错误',
					message: error.response.data.message || 'Status:500，服务器发生错误！'
				})
			} else {
				ElNotification.error({
					title: '请求错误',
					message: error.message || `Status:${error.response.status}，未知错误！`
				})
			}
		} else {
			ElNotification.error({
				title: '请求错误',
				message: '请求服务器无响应！'
			})
		}
		return Promise.reject(error.response)
	}
)

const http = {
	/** get 请求
	 * @param  {string} url 接口地址
	 * @param  {object} params 请求参数
	 * @param  {object} config 参数
	 */
	get: (url: string, params: object = {}, config: object = {}) => {
		return new Promise((resolve, reject) => {
			axios({
				method: 'get',
				url,
				params,
				...config
			})
				.then((response) => resolve(response.data))
				.catch((error) => reject(error))
		})
	},
	/** post 请求
	 * @param  {string} url 接口地址
	 * @param  {object} data 请求参数
	 * @param  {object} config 参数
	 */
	post: (url: string, data: object = {}, config: object = {}) => {
		return new Promise((resolve, reject) => {
			axios({
				method: 'post',
				url,
				data,
				...config
			})
				.then((response) => resolve(response.data))
				.catch((error) => reject(error))
		})
	},
	/** put 请求
	 * @param  {string} url 接口地址
	 * @param  {object} data 请求参数
	 * @param  {object} config 参数
	 */
	put: (url: string, data: object = {}, config: object = {}) => {
		return new Promise((resolve, reject) => {
			axios({
				method: 'put',
				url,
				data,
				...config
			})
				.then((response) => resolve(response.data))
				.catch((error) => reject(error))
		})
	},
	/** patch 请求
	 * @param  {string} url 接口地址
	 * @param  {object} data 请求参数
	 * @param  {object} config 参数
	 */
	patch: (url: string, data: object = {}, config: object = {}) => {
		return new Promise((resolve, reject) => {
			axios({
				method: 'patch',
				url,
				data,
				...config
			})
				.then((response) => resolve(response.data))
				.catch((error) => reject(error))
		})
	},
	/** delete 请求
	 * @param  {string} url 接口地址
	 * @param  {object} data 请求参数
	 * @param  {object} config 参数
	 */
	delete: (url: string, data: object = {}, config: object = {}) => {
		return new Promise((resolve, reject) => {
			axios({
				method: 'delete',
				url,
				data,
				...config
			})
				.then((response) => resolve(response.data))
				.catch((error) => reject(error))
		})
	},
	/** jsonp 请求
	 * @param  {string} url 接口地址
	 * @param  {string} name JSONP回调函数名称
	 */
	jsonp: (url: string, name: string = 'jsonp') => {
		return new Promise((resolve) => {
			const script = document.createElement('script')
			const _id = `jsonp${Math.ceil(Math.random() * 1000000)}`
			script.id = _id
			script.type = 'text/javascript'
			script.src = url
			;(window as any)[name] = (response: any) => {
				resolve(response)
				document.getElementsByTagName('head')[0].removeChild(script)
				try {
					delete (window as any)[name]
				} catch (e) {
					;(window as any)[name] = undefined
				}
			}
			document.getElementsByTagName('head')[0].appendChild(script)
		})
	}
}
export default http
